"""Channel Splitter
.. helpdoc::
This widget takes a signal of an image class and splits that image into the selected channel.  This works for those images that may be incoded as RGB colors and splits into either the R, G, or B component.
"""
"""
<widgetXML>    
    <name>Channel Splitter</name>
    <icon>default.png</icon>
    <tags> 
        <tag>Matplotlib Plotting</tag> 
    </tags>
    <summary>Split an image into channels for each color.</summary>
    <author>
        <authorname>Kyle R. Covington</authorname>
        <authorcontact>kyle@red-r.org</authorcontact>
    </author>
</widgetXML>
"""
from OWRpy import * 
import redRGUI, signals 
import numpy, scipy, pylab

import redRi18n
_ = redRi18n.get_(package = 'base')
class splitImage(OWRpy):
    settings = ['GUI_splitOnChange', 'GUI_splitOnNewData']
    def __init__(self, **kwargs):
        OWRpy.__init__(self, **kwargs)
        self.data = None
        
        """.. rrsignals::"""
        self.inputs.addInput('id0', _('Image'), signals.base.NumpyArray, self.gotImage)
        
        """.. rrsignals::"""
        self.outputs.addOutput('id0', _('Image'), signals.base.NumpyArray)
        
        box = redRGUI.base.widgetBox(self.controlArea, orientation = 'horizontal')
        
        self.GUI_channelSpin = redRGUI.base.spinBox(box, label = "Channel:", min = 1, decimal = 0, callback = self.splitImage)
        self.GUI_splitOnChange = redRGUI.base.TFCheckBox(box, label = "Split On Change", setChecked = True)
        self.GUI_splitOnNewData = redRGUI.base.TFCheckBox(box, label = "Split On New Data", setChecked = True)
        self.GUI_showImage = redRGUI.base.TFCheckBox(box, label = "Show Image", setChecked = False)
        self.GUI_plot = redRGUI.RedRMatplotlib.mplPlot(self.controlArea)
        self.commit = redRGUI.base.commitButton(self.bottomAreaRight, label = _("Commit"), callback = self.commitSplit)
    def gotImage(self, data):
        if data:
            self.data = data.getData()
            shape = self.data.shape
            if len(shape) < 3:
                self.status.setText(_("Only one channel located in the data, applying that channel"))
                self.splitData = self.data
                dim = 1
            else:
                dim = shape[2]
            self.GUI_channelSpin.setMaximum(dim)
            if self.GUI_splitOnNewData.checked() == 'TRUE':
                self.commitSplit()
        else:
            self.data = None
    def splitImage(self):
        if self.GUI_splitOnChange.checked() == "TRUE":
            self.commitSplit()
            
    def commitSplit(self):
        """This function splits the data into one of the channels."""
        if self.data == None:
            self.status.setText(_("No data detected"))
            return
        if len(self.data.shape) < 3:
            newdata = signals.base.NumpyArray(self, data = self.data)
            self.rSend('id0', newdata)
            self.updatePlot(self.splitData)
            return
        
        try:
            self.splitData = self.data[:,:,self.GUI_channelSpin.value()-1]
        except Exception as inst:
            self.status.setText(_('Exception occured while splitting image %s') % inst)
            
            return
        newdata = signals.base.NumpyArray(self, data = self.splitData)
        self.rSend('id0', None)
        self.rSend('id0', newdata)
        if self.GUI_showImage.checked() == "TRUE":
            self.updatePlot(self.splitData)
        
    def updatePlot(self, image):
        self.GUI_plot.subPlot.imshow(image)
        self.GUI_plot.canvas.draw()
